#pragma once

namespace ccastar
{
	typedef void* _HANDLE;
	typedef void* voidp;
	typedef unsigned char uchar;
	typedef unsigned long ulong;
}

struct sLink2
{
	sLink2*	parent = nullptr;
	sLink2*	child = nullptr;
	ccastar::voidp v;
	ccastar::ulong k;
};

struct sLinkHead
{
	ccastar::_HANDLE handle = nullptr;
	ccastar::ulong datasize = 0;
	sLink2* first = nullptr;
	sLink2* tail = nullptr;
	sLink2* cur = nullptr;
	ccastar::ulong nodesCount = 0;
};


class cLink2
{
private:
	sLinkHead head;

public:
	cLink2(ccastar::ulong max);
	~cLink2();

	enum class eInsert { before, after };
	bool insert(ccastar::voidp v, ccastar::ulong k, eInsert e = eInsert::after);
	void remove();
	void remove(ccastar::voidp link);
	void clear();
	void setCur(ccastar::voidp link);
	bool setParent();
	bool setChild();
	void setFirst();
	void setTail();
	ccastar::voidp getValue();
	ccastar::ulong getKey();
	ccastar::voidp getCur();
	ccastar::ulong getNodesCount();
};


class cAstar
{
public:
	struct sCoor { int x, y; };
	struct sNode
	{
		ccastar::uchar state;
		ccastar::ulong distance;
		ccastar::ulong distanceBegin;
		ccastar::ulong distanceEnd;
		sCoor next;
	};
	cAstar();
	~cAstar();
	bool load(ccastar::ulong w, ccastar::ulong h, ccastar::uchar* datas);
	bool search(const sCoor& vStart, const sCoor& vEnd);
	bool next(sCoor& v);

private:
	bool isOut(const sCoor& v);
	ccastar::uchar* _datas = nullptr;
	sNode *_nodes = nullptr;
	ccastar::ulong _width = 0;
	ccastar::ulong _height = 0;
	ccastar::ulong _wh = 0;
public:
	static const ccastar::uchar cUnknown = 0;
	static const ccastar::uchar cWaitChecking = 1;
	static const ccastar::uchar cClose = 2;
	static const ccastar::uchar cObstacle = 1;
};
